package cn.edu.njust.nio;

import cn.edu.njust.EchoClient;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

@Slf4j
public class NioEchoClient implements EchoClient {
    private SocketChannel channel;

    private static String recv(SocketChannel socketChannel) {
        ByteArrayOutputStream bufferStream = new ByteArrayOutputStream();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        int len;

        try {
            while (((len = socketChannel.read(buffer)) > 0)) {
                buffer.flip();
                bufferStream.write(buffer.array(), 0, buffer.limit());
            }

            return bufferStream.toString();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }

    private void send(SocketChannel socketChannel, String message) {

        try {
            socketChannel.write(ByteBuffer.wrap(message.getBytes()));
            // 发完消息记得关闭输出，否则会导致服务端read一直阻塞！(这里不采用拆包机制)
            socketChannel.shutdownOutput();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void connect(int port) {
        try {
            this.channel = SocketChannel.open();
            this.channel.connect(new InetSocketAddress(port));
            log.info("连接服务端成功");
        } catch (IOException e) {
            log.error("连接服务端失败");
            e.printStackTrace();
        }

    }

    @Override
    public String echo(String message) {
        send(channel, message);
        log.info("发送给服务端{}", message);
        return recv(channel);
    }

    @Override
    public void close() {
        try {
            this.channel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
